﻿using Entity;
using Teambuy.Filters;

namespace Services;

/// <summary>
/// 拼团
/// </summary>
[Authorize, ApiDescriptionSettings("拼团服务")]
public class TeamBuy : BaseServices
{
    private readonly ISqlSugarClient db;

    private static readonly SemaphoreSlim _asyncLock = new SemaphoreSlim(1, 1);

    /// <summary>
    /// 
    /// </summary>
    public TeamBuy(ISqlSugarClient db)
    {
        this.db = db;
    }

    /// <summary>
    /// 获取拼团信息
    /// </summary>
    /// <returns></returns>
    public async Task<object> Get(int teamId)
    {
        var data = await db.Queryable<Entity.TeamBuy>()

            .Includes(x => x.Product)

            .Where(x => x.Id == teamId)

            .FirstAsync();

        return Ok(data);
    }

    /// <summary>
    /// 获取我的团员信息
    /// </summary>
    /// <returns></returns>
    public async Task<object> GetChildUser()
    {
        string sql = $@"SELECT  l.userid as userId , count(0) as number , c.name, c.Avatar , c.phone FROM `teambuy` as t 

                        left join `teambuylog` as l 

                        on t.id = l.TeamBuyId

                        left join client as c

                        on c.id = l.userid

                        where t.CratedUserId = {USERID} and l.userid > 0

                        group by l.userid
                        ";

        var data = await db.SqlQueryable<dynamic>(sql).ToPagedListAsync(PageNo, PageSize);

        return Ok(data);
    }

    /// <summary>
    /// 获取我的团员信息
    /// </summary>
    /// <param name="userId"></param>
    /// <returns></returns>
    public async Task<object> GetChildUserTeamLog(int userId)
    {
        string sql = $@"select t.GroupPrice , t.title, p.name , p.image , t.Created , t.state , t.id from teambuylog  as l

                        left join teambuy as t

                        on l.TeamBuyId = t.id

                        left join teambuyproduct as p

                        on t.ProductId = p.id

                        where userid = {userId}";

        var data = await db.SqlQueryable<dynamic>(sql).ToPagedListAsync(PageNo, PageSize);

        return Ok(data);
    }

    /// <summary>
    /// 商户拼团列表
    /// </summary>
    /// <param name="storeId"></param>
    /// <returns></returns>
    public async Task<object> GetList(int storeId, int state)
    {
        var list = await db.Queryable<Entity.TeamBuy>()

            .Where(x => x.StoreId == storeId)

            .WhereIF(state > -1, x => x.State == Entity.TeamBuyState.进行中)

            .Includes(x => x.Product)

            .OrderByDescending(x => x.Id)

            .ToPagedListAsync(PageNo, PageSize);

        return Ok(list);
    }

    /// <summary>
    /// 获取我创建的拼团
    /// </summary>
    /// <param name="teamId"></param>
    /// <returns></returns>
    public async Task<object> GetCreatedTeamBuy(int teamId)
    {
        var data = await db.Queryable<Entity.TeamBuy>()

            .Where(x => x.CratedUserId == USERID).CountAsync();

        return Ok(data);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="storeId"></param>
    /// <param name="state"></param>
    /// <returns></returns>
    public async Task<object> GetMyList(int storeId, int state)
    {
        var list = await db.Queryable<Entity.TeamBuy>()

          .Where(x => x.StoreId == storeId && x.CratedUserId == USERID)

          .WhereIF(state > -1, x => x.State == (Entity.TeamBuyState)state)

          .Includes(x => x.Product)

          .OrderByDescending(x => x.Id)

          .ToPagedListAsync(PageNo, PageSize);

        return Ok(list);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="storeId"></param>
    /// <returns></returns>
    public async Task<object> GetList2(int storeId)
    {
        var list = await db.Queryable<Entity.TeamBuy>()

            .Where(x => x.StoreId == storeId)

            .Where(x => x.State == Entity.TeamBuyState.进行中)

            .Where(x => x.ProductId >= 8 && x.ProductId <= 17)

            .Includes(x => x.Product)

            .OrderByDescending(x => x.Id)

            .ToPagedListAsync(PageNo, PageSize);

        return Ok(list);
    }

    /// <summary>
    /// 检测是否可以加入团购
    /// </summary>
    /// <param name="teamId"></param>
    /// <returns></returns>
    public async Task<object> CheckCanJoin()
    {
        string sql = $@"select count(0) as count from teambuylog as a
                        left join teambuy as b
                        on a.TeamBuyId = b.id
                        where a.UserId = {USERID} and b.state = 0";

        var data = await db.SqlQueryable<dynamic>(sql).FirstAsync();

        if (data.count > 0) return No("您已有参与的拼团");

        return Ok("");
    }

    /// <summary>
    /// 获取拼团用户信息
    /// </summary>
    /// <returns></returns>
    public async Task<object> GetTeamUser(int teamId)
    {
        var data = await db.Queryable<Entity.TeamBuyLog>()

            .Where(x => x.TeamBuyId == teamId)

            .ToListAsync();

        return Ok(data);
    }

    /// <summary>
    /// 加入拼团 基于商户
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    [CheckUser]
    public async Task<object> Join(Dto.TeamBuy.JoinTeamBuyDto e)
    {
        #region 商户和商品信息检测

        //获取商户信息
        var store = await db.Queryable<Entity.Store>().FirstAsync(x => x.Id == e.StoreId);

        //商户不存在
        if (store == null) return No("商户不存在");

        //获取商品信息
        var product = await db.Queryable<Entity.TeamBuyProduct>().FirstAsync(x => x.Id == e.ProductId);

        //商品不存在
        if (product == null) return No("商品不存在");

        #endregion

        try
        {
            string orderNo = Extends.GetOrderNo();

            var order = new Order
            {
                UserId = USERID,

                StoreId = e.StoreId,

                OldPrice = product.GourpPrice,

                PayPrice = product.GourpPrice,

                ProxyId = store.ProxyId,

                OrderNo = orderNo,

                OrderType = OrderType.拼团返利,

                ExtId = 0,
            };

            //记录订单信息
            await db.Insertable(order).ExecuteCommandAsync();

            //记录到缓存中
            await RedisHelper.HSetAsync("CreatedTeambuyParam", orderNo, e);

            return Ok(orderNo);
        }
        catch (Exception)
        {
            return No("加入失败");
        }
    }

    /// <summary>
    /// 获取拼团商品列表
    /// </summary>
    /// <returns></returns>
    public async Task<object> GetProduct()
    {
        var data = await db.Queryable<Entity.TeamBuyProduct>()

            .ToPagedListAsync(PageNo, PageSize);

        return Ok(data);
    }

    /// <summary>
    /// 获取参团列表
    /// </summary>
    /// <returns></returns>
    public async Task<object> GetJoinList()
    {
        var data = await db.Queryable<Entity.TeamBuyLog>()

            .Where(x => x.UserId == USERID)

            .Includes(x => x.TeamBuy, y => y.Product)

            .ToPagedListAsync(PageNo, PageSize);

        return Ok(data);
    }

    /// <summary>
    /// 获取奖品列表
    /// </summary>
    /// <param name="state">true 已领取 false 未领取</param>
    /// <returns></returns>
    public async Task<object> GetPrizeList(bool state)
    {
        var data = await db.Queryable<Entity.TeamBuyPrize>()

            .Where(x => x.UserId == USERID && x.IsResolve == state)

            .Includes(x => x.ExpressInfo, y => y.AddressInfo)

            .Includes(x => x.Product)

            .ToPagedListAsync(PageNo, PageSize);

        return Ok(data);
    }

    /// <summary>
    /// 领取拼团商品
    /// </summary>
    /// <returns></returns>
    public async Task<object> Resolve(int addressId, int teambuyPrizeId)
    {
        var prize = await db.Queryable<Entity.TeamBuyPrize>().FirstAsync(x => x.Id == teambuyPrizeId);

        if (prize.UserId != USERID) return No("领取失败,您不是中奖者");

        var express = new Entity.Express
        {
            AddressId = addressId,

            ExpressState = Entity.ExpressState.待发货,

            StoreId = prize.StoreId,

            UserId = USERID
        };

        try
        {
            db.Ado.BeginTran();

            int expressId = await db.Insertable(express).ExecuteReturnIdentityAsync();

            prize.IsResolve = true;

            prize.ExpressId = expressId;

            await db.Updateable(prize).ExecuteCommandHasChangeAsync();

            db.Ado.CommitTran();

            return Ok("领取成功,请等待商家发货");
        }
        catch (Exception)
        {
            db.Ado.RollbackTran();

            return No("领取失败，请稍后重试");
        }
    }

}
